﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Kalman.Extensions;
using Kalman;
using Kalman.Security;
using Microsoft.AspNetCore.Authorization;
using Newtonsoft.Json.Linq;
using QRCoder;
using QRCoder.Extensions;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using Kalman.Enums;
using AliyunOss;

namespace QuDao.Api.Controllers
{
    /// <summary>
    /// 工具类API：二维码生成，加密解密等
    /// </summary>

    public class UtilsController : ApiControllerBase
    {
        readonly AliyunOssClient oss;
        readonly AppSettings appSettings;

        public UtilsController(AliyunOssClient aliyunOssClient)
        {
            oss = aliyunOssClient;
            appSettings = AppConfig.Instance.GetSection<AppSettings>("AppSettings");
        }

        /// <summary>
        /// 获取二维码
        /// </summary>
        [HttpPost]
        [AllowAnonymous]
        public string GetQrCode(QrCodeModel model)
        {
            if (string.IsNullOrEmpty(model.Text)) throw new AppException("二维码文本内容不能为空");

            //var tenant = TenantBO.Instance.GetItem(tid);
            //if (tenant == null) throw new AppException($"无效的租户：{tid}");

            var level = QRCodeGenerator.ECCLevel.M; 
            switch (model.EccLevel)
            {
                case 'L':
                    level = QRCodeGenerator.ECCLevel.L;
                    break;
                case 'Q':
                    level = QRCodeGenerator.ECCLevel.Q;
                    break;
                case 'H':
                    level = QRCodeGenerator.ECCLevel.H;
                    break;
                default:
                    break;
            }

            if (model.EmbedLogo && (model.EccLevel == 'L' || model.EccLevel == 'M')) level = QRCodeGenerator.ECCLevel.Q;//内嵌logo数据纠错精度不能太低，否则无法识别

            var text = model.Text;
            if(model.IsEncrypt)
            {
                var cryto = new SymmetricCryto(appSettings.SecretKey, SymmetricAlgorithmType.AES_128);
                text = cryto.EncryptString(model.Text);
            }

            using var gen = new QRCodeGenerator();
            using var data = gen.CreateQrCode(text, level);

            /*
             * GetGraphic方法参数说明
                pixelsPerModule	    int		                        绘制每个黑白模块的像素大小
                darkColor	        Color		                    深色/黑色模块的颜色
                lightColor	        Color		                    浅色/白色模块的颜色
                darkColorHtmlHex	string		                    以十六进制表示(例如 #000000)的深色/黑色模块的颜色
                lightColorHtmlHex	string		                    以十六进制表示(例如 #ffffff)的浅色/白色模块的颜色
                icon	            Bitmap	                null	如果为空，则忽略。如果设置，位图将在二维码的中间绘制
                iconSizePercent	    int	                    15	    1-99之间的值。设置图标将覆盖多少二维码，注意数据纠错等级
                iconBorderWidth	    int	                    6	    围绕图标绘制的边框宽度。最小值：1，如果LOGO图片周边没有留白，那么建议设置该参数
                drawQuietZones	    bool	                true	如果为真，则在整个二维码周围绘制一个白色边框
                imgType	            Base64QRCode.ImageType	Png	    设置以Base64字符串编码的图像的图像格式
             */
            var pixelsPerModule = model.PixelsPerModule;
            var darkColor = ColorTranslator.FromHtml(model.DarkColorHtmlHex);//或者ColorTranslator.FromHtml("Black")
            var lightColor = ColorTranslator.FromHtml(model.LightColorHtmlHex);//或者ColorTranslator.FromHtml("White")
            var drawQuietZones = model.DrawQuietZones;

            if (model.IsBase64)
            {
                var base64 = string.Empty;
                using var qrcode = new Base64QRCode(data);
                if (model.EmbedLogo)
                {
                    //var icon = (Bitmap)Image.FromFile(tenant.LogoPath);
                    //var iconSizePercent = 15;
                    //var iconBorderWidth = 8;

                    //base64 = qrcode.GetGraphic(pixelsPerModule, darkColor, lightColor, icon, iconSizePercent, iconBorderWidth, drawQuietZones);
                }
                else
                {
                    base64 = qrcode.GetGraphic(pixelsPerModule, darkColor, lightColor, drawQuietZones);
                }

                return $"data:image/png;base64,{base64}";
            }
            else
            {
                Image img = null;
                using var qrcode = new QRCode(data);

                try
                {
                    if (model.EmbedLogo)
                    {
                        //var icon = (Bitmap)Image.FromFile(tenant.LogoPath);
                        //var iconSizePercent = 15;
                        //var iconBorderWidth = 8;

                        //img = qrcode.GetGraphic(pixelsPerModule, darkColor, lightColor, icon, iconSizePercent, iconBorderWidth, drawQuietZones);
                    }
                    else
                    {
                        img = qrcode.GetGraphic(pixelsPerModule, darkColor, lightColor, drawQuietZones);
                    }

                    if (img == null) throw new AppException("二维码生成失败");

                    using var ms = new MemoryStream();
                    img.Save(ms, ImageFormat.Png);

                    var ossKey = $"ac/qrcode-{DateTime.Now:yyyyMM}/{GuidUtil.New32Lower()}.png";
                    ms.Position = 0;
                    oss.PutImage(ossKey, ms);

                    return oss.Options.BindDomainUrl + ossKey;
                }
                finally
                {
                    img.Dispose();
                }

            }
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="text">待加密的文本内容</param>
        /// <returns></returns>
        [HttpPost]
        public string Encrypt([FromBody] string text)
        {
            var cryto = new SymmetricCryto(appSettings.SecretKey, SymmetricAlgorithmType.AES_128);
            var result = cryto.EncryptString(text);
            return result;
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="text">待解密的文本内容</param>
        /// <returns></returns>
        [HttpPost]
        public string Decrypt([FromBody] string text)
        {
            var cryto = new SymmetricCryto(appSettings.SecretKey, SymmetricAlgorithmType.AES_128);
            var result = cryto.DecryptString(text);
            return result;
        }

        //[HttpGet]
        //public string Pay()
        //{
        //    var jo = PaymentClient.Payment();
        //    return jo.ToJson();
        //}

    }
}
